package com.koron.operation.classes.shift.controller;


import cn.hutool.core.io.IoUtil;
import cn.hutool.poi.excel.ExcelWriter;
import cn.hutool.poi.excel.WorkbookUtil;
import com.github.pagehelper.PageInfo;
import com.koron.bean.base.BaseBean;
import com.koron.bean.base.Response;
import com.koron.bean.query.PageQuery;
import com.koron.bean.system.org.OrgBean;
import com.koron.common.core.business.common.mapper.SystemCommonMapper;
import com.koron.common.core.business.system.feign.SystemFeignService;
import com.koron.common.core.config.ThreadLocalContext;
import com.koron.common.core.util.OrgCacheUtils;
import com.koron.operation.classes.schedule.bean.dto.StaffShiftInfo;
import com.koron.operation.classes.schedule.bean.po.ClassesSchedule;
import com.koron.operation.classes.schedule.bean.query.ScheduleQuery;
import com.koron.operation.classes.schedule.bean.query.ShiftStaffQuery;
import com.koron.operation.classes.schedule.bean.vo.ClassesStaffVO;
import com.koron.operation.classes.schedule.service.ClassesScheduleService;
import com.koron.operation.classes.shift.bean.dto.AdjustRecordDTO;
import com.koron.operation.classes.shift.bean.dto.ChangeShiftDTO;
import com.koron.operation.classes.shift.bean.dto.ShiftRecordDTO;
import com.koron.operation.classes.shift.bean.param.ClassesAdjustParam;
import com.koron.operation.classes.shift.bean.query.ShiftQuery;
import com.koron.operation.classes.shift.bean.query.ShiftRecordQuery;
import com.koron.operation.classes.shift.bean.vo.ShiftRecordVO;
import com.koron.operation.classes.shift.service.ShiftService;
import com.koron.operation.util.OperationCodeTools;
import com.koron.operation.util.SortUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.SneakyThrows;
import org.apache.poi.ss.usermodel.Workbook;
import org.koron.ebs.mybatis.ADOConnection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 交接班综合接口
 *
 * @author jzp
 * @since 2021-10-27 14:33:52
 */
@Api(tags = "交接班接口")
@RestController
@RequestMapping("shift")
public class ShiftController {

    @Autowired
    private ShiftService shiftService;
    @Autowired
    private OrgCacheUtils orgCacheUtils;
    @Autowired
    private ClassesScheduleService classesScheduleService;
    @Autowired
    private SystemFeignService systemFeignService;

    private String getCurrDs() {
        return ThreadLocalContext.get().getCurrDs();
    }

    @ApiOperation(value = "交接班次查询")
    @GetMapping("info")
    public Response<ChangeShiftDTO> info(ShiftRecordQuery shiftQuery) {
        return Response.ok(ADOConnection.runTask(getCurrDs(), shiftService, "getChangeShift", ChangeShiftDTO.class, shiftQuery));
    }

    @ApiOperation(value = "交接班记录分页查询")
    @GetMapping("page")
    public Response<PageInfo<ShiftRecordVO>> page(PageQuery pageQuery, ShiftRecordQuery query) {
        return Response.ok(ADOConnection.runTask(getCurrDs(), shiftService, "page", PageInfo.class, pageQuery, query));
    }

    @ApiOperation(value = "交接班记录详情查询")
    @GetMapping
    public Response<ShiftRecordDTO> selectOne(ShiftQuery query) {
        return Response.ok(ADOConnection.runTask(getCurrDs(), shiftService, "detail", ShiftRecordDTO.class, query));
    }

    @ApiOperation(value = "人员调整记录查询")
    @GetMapping("adjustRecord")
    public Response<AdjustRecordDTO> adjustRecord(String thisShiftId, String nextShiftId) {
        return Response.ok(ADOConnection.runTask(getCurrDs(), shiftService, "adjustRecord", AdjustRecordDTO.class, thisShiftId, nextShiftId));
    }

    @ApiOperation(value = "交接事项查询")
    @GetMapping("tips")
    public Response<List> tips(String deptId, String locationId, String staffType) {
        return Response.ok(ADOConnection.runTask(getCurrDs(), shiftService, "getTipByCondition", List.class, deptId, locationId, staffType));
    }

    @ApiOperation(value = "首页今日值班人员信息")
    @GetMapping("staffs")
    public Response<List<ClassesStaffVO>> staffs(@RequestParam @ApiParam(required = true, value = "部门id") String deptId,
                                                 @RequestParam @ApiParam(required = false, value = "位置id") String locationId) {
        return Response.ok(ADOConnection.runTask(getCurrDs(), shiftService, "staffs", List.class, deptId, locationId));
    }

    @ApiOperation(value = "新首页今日值班人员信息")
    @GetMapping("home")
    public Response<Map<String, List<ClassesStaffVO>>> home(@RequestParam @ApiParam(required = true, value = "部门id") String deptId) {
        Map<String, List<ClassesStaffVO>> home = ADOConnection.runTask(getCurrDs(), shiftService, "home", Map.class, deptId);
        OrgBean orgBean = orgCacheUtils.getOrgById(deptId);
        // 获取改部门下的所有单位
        List<OrgBean> data = ADOConnection.runTask(factory -> {
            SystemCommonMapper mapper = factory.getMapper(SystemCommonMapper.class);
            String levelPath = "/".equals(orgBean.getLevelPath()) ? orgBean.getLevelPath() + deptId : orgBean.getLevelPath() + "/" + deptId;
            return mapper.queryOrgListLikeLevelPath(levelPath);
        }, List.class);
        data.add(0, orgBean);
        SortUtil.deptSortByTreeLevel(data, orgBean.getLevel()).stream().map(BaseBean::getId).forEach(orgId -> {
            home.putAll(ADOConnection.runTask(getCurrDs(), shiftService, "home", Map.class, orgId));
        });
        return Response.ok(home);
    }

    @ApiOperation(value = "移动端值班领导信息")
    @GetMapping("leader")
    public Response<List<Map<String, Object>>> leader() {
        return Response.ok(ADOConnection.runTask(getCurrDs(), shiftService, "leader", List.class));
    }

    @ApiOperation(value = "移动端人员值班信息")
    @GetMapping("staffShift")
    public Response<StaffShiftInfo> staffShift(ShiftStaffQuery query) {
        return Response.ok(ADOConnection.runTask(getCurrDs(), shiftService, "staffShift", StaffShiftInfo.class, query));
    }

    @ApiOperation(value = "查询指定单位的值班地点")
    @GetMapping("locations")
    public Response<List<ClassesSchedule>> locations(String deptId) {
        ScheduleQuery query = new ScheduleQuery();
        query.setDeptId(deptId);
        query.setStatus(Collections.singletonList(0));
        List<ClassesSchedule> list = ADOConnection.runTask(getCurrDs(), classesScheduleService, "list", List.class, query);
        // 去重
        Map<Object, Boolean> map = new HashMap<>();
        List<ClassesSchedule> collect = list.stream().filter(i -> map.putIfAbsent(i.getLocationId(), Boolean.TRUE) == null).filter(e -> !StringUtils.isEmpty(e.getLocationName())).collect(Collectors.toList());
        return Response.ok(collect);
    }

    @ApiOperation(value = "人员调整")
    @PostMapping("adjustStaff")
    public Response<ChangeShiftDTO> adjustStaff(@RequestBody ClassesAdjustParam classesAdjustParam) {
        ADOConnection.runTask(getCurrDs(), shiftService, "adjustStaff", Void.class, classesAdjustParam);
        return Response.ok("调整成功",null);
    }

    @ApiOperation(value = "交接班记录详情保存或更新")
    @PostMapping("save")
    public Response save(@RequestBody ShiftRecordDTO shiftRecordDTO) {
        ADOConnection.runTask(getCurrDs(), shiftService, "saveOrUpdate", Boolean.class, shiftRecordDTO);
        return Response.ok();
    }

    @ApiOperation(value = "交班")
    @PutMapping("handover")
    public Response handover(@RequestBody ShiftRecordDTO shiftRecordDTO) {
        ADOConnection.runTask(getCurrDs(), shiftService, "handover", Boolean.class, shiftRecordDTO);
        return Response.ok("交班成功",null);
    }

    @ApiOperation(value = "接班")
    @PutMapping("takeover")
    public Response takeover(String recordId) {
        ADOConnection.runTask(getCurrDs(), shiftService, "takeover", Boolean.class, recordId);
        return Response.ok("接班成功",null);
    }

    @ApiOperation(value = "直接接班")
    @PutMapping("straightTakeover")
    public Response straightTakeover(@RequestParam(required = false) String thisShiftId, String nextShiftId) {
        ADOConnection.runTask(getCurrDs(), shiftService, "straightTakeover", Boolean.class, thisShiftId, nextShiftId);
        return Response.ok("接班成功",null);
    }

    @ApiOperation(value = "接班驳回")
    @PutMapping("reject")
    public Response reject(String recordId) {
        ADOConnection.runTask(getCurrDs(), shiftService, "reject", Boolean.class, recordId);
        return Response.ok("驳回成功",null);
    }

    @SneakyThrows
    @ApiOperation(value = "导出数据")
    @GetMapping("export")
    public void export(ShiftRecordQuery query, HttpServletResponse response) {
        String path = "excel/shiftRecord.xlsx";
        ClassPathResource classPathResource = new ClassPathResource(path);
        Workbook book = WorkbookUtil.createBook(classPathResource.getInputStream());
        ExcelWriter writer = new ExcelWriter(book, "交接班记录");
        String fileName = OperationCodeTools.getShiftRecordCode();

        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
        response.setHeader("Content-Disposition","attachment;filename="+ fileName +".xlsx");

        List<?> exportList = ADOConnection.runTask(getCurrDs(), shiftService, "exportList", List.class, query);
        writer.passRows(3);
        writer.write(exportList, false);

        ServletOutputStream out=response.getOutputStream();
        writer.flush(out, true);
        writer.close();
        IoUtil.close(out);
    }

    /**
     * 打印交接班记录
     */
    @ApiOperation(value = "打印交接班记录(需要先 安装 打印控件)")
    @GetMapping("printShift")
    public Response<String> printShift(ShiftQuery query) {
        return Response.ok(ADOConnection.runTask(getCurrDs(), shiftService, "printShift", String.class, query));
    }

    /**
     * 月度排班表
     */
    @ApiOperation(value = "月度排班表")
    @GetMapping("getMonthClass")
    public Response<List> getMonthClass(ScheduleQuery query) {
        return Response.ok(ADOConnection.runTask(getCurrDs(), shiftService, "getMonthClass", List.class, query));
    }

}
